# python re模块：
import re

msg = "孙涵青风水月桃白白"
pattern = re.compile("孙涵")
result = pattern.match(msg)
print(result)

# 使用正则re模块方法：match
s = "青风水月孙涵桃白白"
# match方法会将正则与字符串从头开始匹配，如果第一下没有匹配成功则直接返回None
result = re.match("孙涵",s)
print(result)

# search是进行正则字符串查找的方法，查找的是整个字符串（也只能匹配一个，找到符合规则的就返回，但不一定从头开始）
result = re.search("孙涵",s)
print(result)
# 查找返回位置
print(result.span())
# 使用group提取到匹配的内容
print(result.group())
print(result.groups())

# findall函数则会将字符串中所有符合条件的子串找出，返回出一个列表（没有则空列表）
s = "青风水月孙涵桃白白孙涵"
result = re.findall("孙涵",s)
print(result)

# fullmatch函数是全字符串匹配,相当于字符串比较相等
s1 = "孙涵"
result = re.fullmatch("孙涵",s)
result1 = re.fullmatch("孙涵",s1)
print(result)
print(result1)
print("\n")

# 匹配的数字（都只能匹配一个）
print(re.search(r"\d",r'python893_\n abc'))    # \d表示匹配数字
print(re.search(r"[0-9]",r'python893_\n abc'))    # [0-9]表示从0-9开始匹配

# 匹配单词字符（单个）
print(re.search(r"\w",r'python893_\n abc'))
# （\W表示匹配非单词字符）下划线属于单词字符
print(re.search(r"\W",r'python893_\n abc'))    # 结果第一个“\”表示转义，后面才是真正的符号
print("\n")

"""
表示数量的元字符：（在谁后面就针对谁）
[]   表示的是一个范围
()   表示分组
*   匹配前一个字符出现0次或者无限次，即可有可无
+   匹配前一个字符出现1次或者无限次，即至少有1次
？  匹配前一个字符出现0次或者1次，即要么没有，要么有1次
{m}     匹配前一个字符出现m次
{m,}    匹配前一个字符至少出现m次
{m,n}   匹配前一个字符出现从m到n次
"""
print(re.search(r"\d+",r'python893_\n abc'))
print(re.search(r"\S*",r'python893_\n abc'))    # \S表示匹配非空白字符
print(re.search(r"\d{2}",r'python893_\n abc'))
# [a-zA-Z]表示一个字母大小写都可以
print(re.search(r"[a-zA-Z]+",r'python893_\n abc'))
print("\n")

"""
表示边界的元字符：（限定开始与结尾的匹配,大写表示反义）
.   用于匹配除换行符（\n）之外的所有字符
^   匹配开始位置，多行模式下匹配每一行的开始(也有取反的意思，区分应用场景)
$   匹配字符串结尾
\b   匹配一个单词的边界
\B   匹配非单词边界
\s   匹配字符串中所有空格
"""
s2 = "awhahlf@163.com,affafafaaaaaaaaaaaaa@163.com,abcdefg@163.com afa_@163.com"
# 匹配正确的网页邮箱地址
print(re.search(r"^[a-zA-Z]\w{5,17}@163.com",s2))
print(re.findall(r"\b[a-zA-Z]\w{5,17}@163.com",s2))
# ^还有取反的意思(加在中括号里面是取反，外面是匹配开始位置)
s3 = "123124343abc"
print(re.search("[^0-9]+",s3))
print("\n")

# 用户名可以是字母或者数字，不能是数字开头，用户名长度必须在6位以上
user = "@&admin001#&"
result = re.search("^[a-zA-Z][0-9a-zA-Z]{5,}$",user)   # 不加^和$会匹配出admin001
print(result)

msg = "a*py ab.txt bb.py kk.png uu.py apyb.txt"
result = re.findall(r"\w+\.py\b",msg)
print(result)
print("\n")

# 手机号码验证的正则表达式
# re.match("1[35789]\d{9}$",phone)

# 匹配数字0-100
n = "100"
# |表示或者，(word|word|word)表示一个单词一个单词之间的或者，[abc]表示的是一个字母一个字母的或者（或者a或者b或者c）
result = re.match(r"[0-9]?\d?$|100$",n)
print(result)

"""
在分组的时候还可以结合|来使用
result = re.match(r"(\d{3}|\d{4})-(\d{8})$",phone)
print(result)

不需要引用分组的内容：
    result = re.match(r"<[0-9a-zA-Z]+>(.+)</[0-9a-zA-Z]+>",msg)
    print(result)
    print(result.group(1))
    
引用分组匹配内容：
    1.number   \number表示引用第number组的数据
        msg = "<html><h1>abc</h1></html>"
        result = re.march(r"<([0-9a-zA-Z]+)><([0-9a-zA-Z]+)>(.+)</\2></\1>$",msg)
        print(result)
    2.?P<名字>   
        msg = "<html><h1>abc</h1></html>"
        result = re.match(r"<(?P<name1>\w+)><(?P<name2>\w+)>(.+)</(?P=name2)></(?P=name1)>",msg)
        print(result)
        print(result.group(1))
"""
# 起名的方式：(?P<名字>正则)  (?P=名字)--->引用
msg = "<html><h1>abc</h1></html>"
# (.+)是匹配任意字符（至少一个），表示标签内的内容
result = re.match(r"<(?P<name1>\w+)><(?P<name2>\w+)>(.+)</(?P=name2)></(?P=name1)>",msg)
print(result)
# result.group(0)获取组中的整个字符串
print(result.group(0))
# result.group(1)获取组中的第一个个字符串（有匹配才能调用）
print(result.group(1))
print(result.group(2))
print(result.group(3))

# sub函数起到一个替换的作用  sub(正则表达式，“新内容”，string)
result = re.sub(r"\d+","100","java:99,python:99")
print(result)

# repl里面还可以用函数替代
def func(temp):
    num = temp.group()
    num1 = int(num) + 1
    return str(num1)

result = re.sub(r"\d+",func,"java:99,python:99")
print(result)

# 正则中的spilt函数可以按多个要求进行切割，并保存到列表
result = re.split(r"[,:]","java:99,python:99")
print(result)

"""
python里数量词默认是贪婪的（在少数语言里也可能是默认非贪婪），总是尝试匹配尽可能多的字符
非贪婪则相反，总是尝试匹配尽可能少的字符
在“*”，“?”，“+”，“{m,n}”后面加上“?”，使贪婪变成非贪婪
"""
# 默认是贪婪的
msg = "abc123abc"
# result = re.match(r"abc(\d+?)",msg)
result = re.match(r"abc(\d+?)",msg)    # 将贪婪转化为非贪婪
print(result)

# 对网址源码进行处理
path = "https://i2.hdslb.com/bfs/archive/b6d3a2c5cda290e7333c0c488031fb59953d88e8.jpg"
result = re.search(r"https://(.+)",path)
image_path = result.group(0)
print(image_path)

import requests

response = requests.get(image_path)
with open("python.jpg", "wb") as wstream:
    wstream.write(response.content)
